昨天介紹到了如何使用 fabricjs
的基本用法,今天就拿來做一些應用吧,這次主要是參考了 imgflip 的功能,主要是可以選擇圖片或匯入圖片,並且加入自己的文字,最後在匯出。
首先, imgfilp
有提供一個接口,可以拿到圖片,所以我們就使用這個接口
getMemesJson() {
return fetch('https://api.imgflip.com/get_memes')
.then(response => response.json())
}
接著在讀取完後讀入現在的圖片
loadCurrentImg() {
const currentFile = this.memes[this.currentIndex]
this.loadImg(currentFile.url)
}
目前的做法是當換掉圖片時就把所有之前的東西都刪掉,也就是文字跟圖片這兩種,如果只想刪掉特定種類的話,可以使用 fabric Canvas
的 getObjects
方法,拿回現在所有的物件,並且挑選你想要的來刪除。
cleanAll() {
this.fabricCanvas.clear()
this.editTexts = []
}
接著用昨天介紹的讀取圖片方式來使用,傳入我們從 api 拿回來的位置,並且重設定一下寬高,目前是維持在等寬 600 高度照比例縮小的方式,所以一開始我們會需要算需要縮放的比例,接著更新到 canvas
身上,接著把 img
設定成不能選取及游標顯示不在是拖曳,因為我們希望圖片是當成背景來使用,所以把控制的操作都關閉。scaleToHeight
則是另一種使用方式讓圖片變成指定的高度,接著最後一樣要記得加到 canvas
裡面,這邊還有一點值得注意的是因為 fabric
是依照加入的先後順序來決定物件的層級,但因為我們需要圖片一直在最底部,所以使用了 sendToBack
把他移到最底層,不然可能會發生文字被圖片蓋住的情況。
loadImg(path) {
this.cleanAll()
fabric.Image.fromURL(
path,
img => {
const maxWidth = 600
const scale = maxWidth / img.width
this.height = scale * img.height
this.width = scale * img.width
this.fabricCanvas.setHeight(this.height)
this.fabricCanvas.setWidth(this.width)
const newImg = img.set({
hoverCursor: 'default',
selectable: false
})
newImg.scaleToHeight(this.height)
newImg.scaleToWidth(this.width)
this.fabricCanvas.add(newImg)
this.addText()
// 讓圖片一直在最底層 不會影響到字的顯示
this.fabricCanvas.sendToBack(newImg)
}
)
}
接著就可以繼續做修改文字的部分了,在新增文字的時候一樣可以選擇顏色、字體大小等等之類,接著除了加到 canvas
裡面之外,我們也自己另外存了一份給等下的編輯使用
addText() {
const editText = new fabric.IText('點擊編輯', {
fill: '#ffffff',
stroke: '#000000',
fontSize: 40,
fontFamily: 'Microsoft JhengHei, PMingLiU, sans-serif'
})
this.editTexts.push(editText)
this.fabricCanvas.add(editText)
}
接著在畫面裡使用
<div
v-for="(item, index) in editTexts"
class="edit_texts"
>
<el-input
:value="item.text"
@input="(val) => textChange(val, index)"
></el-input>
</div>
接著就是一般的更新,我們需要使用 set
來變更 IText
物件的值,有一點值得要注意的是需要在變更之後使用 renderAll
textChange(val, index) {
const target = this.editTexts[index]
target.set('text', val)
this.render()
},
render() {
this.fabricCanvas.renderAll()
}
到這邊應該基本的雛形就有出來了,成果像這樣
今天有做了一個雛型出來,明天繼續完善!